#include <iostream>
#include <math.h>
#include <fftw3.h>
#include "WaveCore.h"

#define MAX_N 200000
#include <opencv2/opencv.hpp>
using namespace std;
namespace mmjd
{
    namespace yuyin
    {
        void WaveCore::showData(double *data, int length, int width, int height, int beam, double m_max) {
            double max = m_max;

            for (int i = 0; i < length; i++) {
                if (max < fabs(data[i])) {
                    max = fabs(data[i]);
                };
            }
            if (max > 1e15 || max == INFINITY) {
                max = 1e15;
            }

            cv::Mat outImg = cv::Mat(height, width * beam, CV_8UC1);
            outImg = 255;

            for (int i = 0; i < width; i++) {
                int low_bond = length * i / width;
                int uper_bond = length * (i + 1) / width - 1;
                double avg;
                if (uper_bond > low_bond) {
                    double sum = 0;
                    for (int tmp = low_bond; tmp <= uper_bond; tmp++) {
                        sum += data[tmp];
                    }
                    avg = sum / (uper_bond - low_bond + 1);
                } else {
                    avg = data[low_bond];

                }
                for (int dlt = 0; dlt < beam; dlt++) {
                    int x = i * beam + dlt;
                    if (avg < 1e15 || avg == INFINITY) {
                        for (int j = (height - 1 - (fabs(avg / max) * height)); j < height; j++) {
                            if (j > 0 && j < height) outImg.at<uint8_t>(j, x) = 0;
                        }
                        //std::cout<<std::endl;
                    }
                }
            }
            cv::imshow("test",outImg);
            cv::waitKey(10);
        }

        void WaveCore::processVoice(std::vector<short> &a, int length, double *out_r) {
            fftw_complex *in, *out;
            fftw_plan p;

            in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex)*length);
            out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex)*length);
            //cout<<"\n\n++++++++++++++++++++++++++++++\n\n"<<endl;
            for (int i = 0; i < length; i++) {
                in[i][0] = (double) a[i];
                in[i][1] = 0.0;

                //      cout << in[i][0]<<" ";
            }
            p = fftw_plan_dft_1d(length, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
            fftw_execute(p);

            //    cout<<"\n\n............................\n\n"<<endl;
            for (int i = 0; i < length; i++) {
                out_r[i] = sqrt(out[i][0] * out[i][0] + out[i][1] * out[i][1]);
                //cout << out_r[i]<<" \t ";
            }

            fftw_free(in);
            fftw_free(out);
        }

        bool WaveCore::isVoise(std::vector<short> &in, int length) {
            double out[MAX_N+2000];
            memset(out, 0, sizeof(double) * MAX_N);
            processVoice(in, length, out);
            //showData(out,(length/2)*1/2,200,200,5,20000);
            double sum = 0;
            int count = 0;
            for (int i = length / 40; i < length / 4; i++) {
                sum += out[i] * out[i];
                count++;
            }
            sum /= count;
            //cout << endl;
            //cout << "sqr sum average: (" << sum << ")" << endl;
            if (sum > 1 * 1e7) {
                //cout << " (" << sum << ")\n";
                sum = 0;
                return true;

            } else {
                //cout << " (" << sum << ")" << " )\n";
                sum = 0;
                return false;
            }

        }
    }
}



